package com.xueyi.workflow.service.impl;

import com.xueyi.workflow.domain.dto.PersonnelQueryRequest;
import com.xueyi.workflow.domain.vo.PersonnelInfo;
import com.xueyi.workflow.domain.dto.ProcessFormBindDto;
import com.xueyi.workflow.domain.dto.ProcessMetaDto;
import com.xueyi.workflow.domain.dto.WfProcessVersionDto;
import com.xueyi.workflow.domain.query.ProcessFormBindQuery;
import com.xueyi.workflow.domain.query.ProcessMetaQuery;
import com.xueyi.workflow.domain.vo.WfWorkbenchVo;
import com.xueyi.workflow.manager.ProcessMetaManager;
import com.xueyi.workflow.service.IWfProcessService;
import com.xueyi.workflow.service.IWfProcessVersionService;
import com.xueyi.workflow.service.ProcessFormBindService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xueyi.common.security.utils.SecurityUtils;
import com.xueyi.workflow.service.IWorkflowUserService;
import com.xueyi.common.core.web.result.R;
import com.xueyi.system.api.organize.domain.dto.SysUserDto;
import com.xueyi.system.api.organize.feign.RemoteUserService;

import jakarta.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 流程Service业务层处理
 *
 * @author xueyi
 * @date 2024-07-03
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class WfProcessServiceImpl implements IWfProcessService {

    private final ProcessMetaManager processMetaManager;
    private final IWfProcessVersionService wfProcessVersionService;
    private final ProcessFormBindService processFormBindService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private IWorkflowUserService workflowUserService;

    @Autowired
    private RemoteUserService remoteUserService;

    /**
     * 获取当前用户ID
     */
    private String getCurrentUserId() {
        try {
            return SecurityUtils.getUserId().toString();
        } catch (Exception e) {
            log.warn("获取当前用户ID失败，使用默认值: {}", e.getMessage());
            return "admin"; // 默认用户
        }
    }

    /**
     * 获取授权流程列表
     */
    @Override
    public List<Map<String, Object>> getAuthorizedProcessList() {
        // 查询所有启用的流程元数据
        ProcessMetaQuery query = new ProcessMetaQuery();
        query.setStatus("0"); // 启用状态
        List<ProcessMetaDto> processList = processMetaManager.selectList(query);
        
        // 转换为前端需要的格式，并为每个流程添加最新的流程版本ID
        return processList.stream().map(process -> {
            Map<String, Object> processMap = new HashMap<>();
            processMap.put("id", process.getId());
            processMap.put("processKey", process.getProcessKey());
            processMap.put("processName", process.getName());
            processMap.put("version", process.getVersion());
            processMap.put("status", "published");
            
            // 获取最新的流程版本ID
            try {
                WfProcessVersionDto latestVersion = wfProcessVersionService.getProcessVersionByKey(
                    process.getProcessKey(), 
                    process.getVersion()
                );
                if (latestVersion != null) {
                    processMap.put("processVersionId", latestVersion.getId());
                    processMap.put("latestVersion", latestVersion.getVersion());
                } else {
                    // 如果没有找到指定版本，尝试获取最新版本
                    Integer latestVersionNum = wfProcessVersionService.getLatestVersionByKey(process.getProcessKey());
                    if (latestVersionNum != null) {
                        WfProcessVersionDto versionInfo = wfProcessVersionService.getProcessVersionByKey(
                            process.getProcessKey(), 
                            latestVersionNum
                        );
                        if (versionInfo != null) {
                            processMap.put("processVersionId", versionInfo.getId());
                            processMap.put("latestVersion", versionInfo.getVersion());
                        }
                    }
                }
            } catch (Exception e) {
                // 如果获取流程版本失败，记录日志但不影响流程列表返回
                System.err.println("获取流程 " + process.getProcessKey() + " 的版本信息失败: " + e.getMessage());
            }
            
            // 获取流程表单绑定信息
            try {
                ProcessFormBindQuery formBindQuery = new ProcessFormBindQuery();
                formBindQuery.setProcessId(process.getId().toString()); // 转换为String类型
                List<ProcessFormBindDto> formBindList = processFormBindService.selectList(formBindQuery);
                if (formBindList != null && !formBindList.isEmpty()) {
                    ProcessFormBindDto formBindInfo = formBindList.get(0);
                    processMap.put("formId", formBindInfo.getFormId());
                    processMap.put("formName", formBindInfo.getFormName());
                    processMap.put("bindType", formBindInfo.getBindType());
                } else {
                    processMap.put("formId", null);
                    processMap.put("formName", null);
                    processMap.put("bindType", null);
                }
            } catch (Exception e) {
                // 如果获取表单绑定信息失败，记录日志但不影响流程列表返回
                System.err.println("获取流程 " + process.getProcessKey() + " 的表单绑定信息失败: " + e.getMessage());
                processMap.put("formId", null);
                processMap.put("formName", null);
                processMap.put("bindType", null);
            }
            
            return processMap;
        }).collect(Collectors.toList());
    }

    /**
     * 获取流程表单绑定信息
     */
    @Override
    public Map<String, Object> getProcessFormBind(String processId) {
        // TODO: 实现真实的数据库查询
        Map<String, Object> bindInfo = new HashMap<>();
        bindInfo.put("processId", processId);
        bindInfo.put("formId", 1L);
        bindInfo.put("formName", "请假申请表");
        bindInfo.put("formType", "dynamic");
        return bindInfo;
    }

    /**
     * 获取工作台数据
     */
    @Override
    public WfWorkbenchVo getWorkbenchData() {
        try {
            // 获取当前用户ID
            String currentUserId = getCurrentUserId();
            
            WfWorkbenchVo data = new WfWorkbenchVo();
            
            // 获取待办任务数量
            try {
                long pendingTasks = taskService.createTaskQuery()
                    .taskAssignee(currentUserId)
                    .count();
                data.setPendingTasks(pendingTasks);
            } catch (Exception e) {
                log.warn("获取待办任务数量失败: {}", e.getMessage());
                data.setPendingTasks(0L);
            }
            
            // 获取进行中的流程数量
            try {
                long runningProcesses = runtimeService.createProcessInstanceQuery()
                    .active()
                    .count();
                data.setRunningProcesses(runningProcesses);
            } catch (Exception e) {
                log.warn("获取进行中流程数量失败: {}", e.getMessage());
                data.setRunningProcesses(0L);
            }
            
            // 获取已完成的流程数量
            try {
                long completedProcesses = historyService.createHistoricProcessInstanceQuery()
                    .finished()
                    .count();
                data.setCompletedProcesses(completedProcesses);
            } catch (Exception e) {
                log.warn("获取已完成流程数量失败: {}", e.getMessage());
                data.setCompletedProcesses(0L);
            }
            
            // 获取我发起的流程数量
            try {
                long myProcesses = runtimeService.createProcessInstanceQuery()
                    .startedBy(currentUserId)
                    .active()
                    .count();
                data.setMyProcesses(myProcesses);
            } catch (Exception e) {
                log.warn("获取我发起的流程数量失败: {}", e.getMessage());
                data.setMyProcesses(0L);
            }
            
            log.info("工作台数据获取成功: {}", data);
            return data;
        } catch (Exception e) {
            log.error("获取工作台数据失败", e);
            // 返回默认数据
            WfWorkbenchVo data = new WfWorkbenchVo();
            data.setPendingTasks(5L);
            data.setRunningProcesses(3L);
            data.setCompletedProcesses(12L);
            data.setMyProcesses(4L);
            return data;
        }
    }

    /**
     * 导出历史数据
     */
    @Override
    public void exportHistoryData(String type, String startDate, String endDate, HttpServletResponse response) {
        // TODO: 实现历史数据导出逻辑
        System.out.println("导出历史数据: " + type + ", " + startDate + " - " + endDate);
    }

    /**
     * 根据角色、部门、岗位ID获取人员列表
     */
    @Override
    public List<PersonnelInfo> getPersonnelList(PersonnelQueryRequest request) {
        log.info("获取人员列表，请求参数: {}", request);
        
        Set<Long> allUserIds = new java.util.HashSet<>();
        
        // 根据角色ID获取用户
        if (request.getRoleIds() != null && !request.getRoleIds().isEmpty()) {
            Set<Long> roleUserIds = workflowUserService.getUserIdsByRoleIds(
                request.getRoleIds().stream().collect(Collectors.toSet())
            );
            allUserIds.addAll(roleUserIds);
        }
        
        // 根据部门ID获取用户
        if (request.getDeptIds() != null && !request.getDeptIds().isEmpty()) {
            Set<Long> deptUserIds = workflowUserService.getUserIdsByDeptIds(
                request.getDeptIds().stream().collect(Collectors.toSet())
            );
            allUserIds.addAll(deptUserIds);
        }
        
        // 根据岗位ID获取用户
        if (request.getPostIds() != null && !request.getPostIds().isEmpty()) {
            Set<Long> postUserIds = workflowUserService.getUserIdsByPostIds(
                request.getPostIds().stream().collect(Collectors.toSet())
            );
            allUserIds.addAll(postUserIds);
        }
        
        // 直接添加用户ID
        if (request.getUserIds() != null && !request.getUserIds().isEmpty()) {
            allUserIds.addAll(request.getUserIds());
        }
        
        log.info("获取到的用户ID集合: {}", allUserIds);
        
        // 调用用户服务获取真实的用户信息
        List<PersonnelInfo> personnelList = new java.util.ArrayList<>();
        
        for (Long userId : allUserIds) {
            try {
                // 调用远程用户服务获取用户信息
                R<SysUserDto> userResult = remoteUserService.selectByIdInner(userId);
                
                if (userResult != null && userResult.getData() != null) {
                    SysUserDto user = userResult.getData();
                    PersonnelInfo info = new PersonnelInfo();
                    info.setId(userId);
                    info.setNickName(user.getNickName() != null ? user.getNickName() : user.getUserName());
                    info.setUserName(user.getUserName());
                    info.setAvatar(user.getAvatar() != null ? user.getAvatar() : "");
                    info.setType("user");
                    info.setSource("工作流人员配置");
                    personnelList.add(info);
                    
                    log.debug("获取用户信息成功: userId={}, nickName={}, userName={}", 
                        userId, info.getNickName(), info.getUserName());
                } else {
                    log.warn("获取用户信息失败，用户ID: {}, 响应: {}", userId, userResult);
                    // 如果获取失败，跳过该用户，不添加测试数据
                }
            } catch (Exception e) {
                log.error("调用用户服务失败，用户ID: {}", userId, e);
                // 如果调用失败，跳过该用户，不添加测试数据
            }
        }
        
        log.info("返回人员列表，共{}人", personnelList.size());
        return personnelList;
    }
} 